package pe.com.ztaxi.taxis.dao;

import java.util.Date;
import java.util.List;

import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import pe.com.ztaxi.taxis.model.OrdenServicio;

public interface OrdenServicioDAO extends JpaRepository<OrdenServicio, Integer> {
	
	@Query("SELECT o FROM OrdenServicio o WHERE o.pasajero.empresa.codEmpresa = :codigoEmpresa AND o.estado = 'Pendiente' OR o.estado = 'En Proceso' OR o.estado = 'Asignado' ORDER BY o.fechaServicio")
    public List<OrdenServicio> buscarPorEstadoPendienteEnProceso(@Param("codigoEmpresa") Integer codigoEmpresa);
	
	@Query("SELECT o FROM OrdenServicio o WHERE o.estado = 'Pendiente' OR o.estado = 'En Proceso' OR o.estado = 'Asignado' ORDER BY o.fechaServicio")
    public List<OrdenServicio> buscarPorEstadoPendienteEnProceso();
	
	@Query("SELECT o FROM OrdenServicio o WHERE o.estado = 'Pendiente' ORDER BY o.fechaServicio")
    public List<OrdenServicio> buscarPorEstadoPendiente();
	
	@Query("SELECT o FROM OrdenServicio o WHERE (o.estado = 'En Proceso' OR o.estado = 'Asignado') ORDER BY o.fechaServicio")
    public List<OrdenServicio> buscarPorEstadoEnProceso();
	
	@Query("SELECT o FROM OrdenServicio o WHERE (o.estado = 'En Proceso' OR o.estado = 'Asignado') AND o.horaLlegadaOrigen = null ORDER BY o.fechaServicio")
	public List<OrdenServicio> buscarPorEstadoEnProcesoSinHoraLlegadaOrigen();
	
	@Query("SELECT o FROM OrdenServicio o WHERE (o.estado = 'En Proceso' OR o.estado = 'Asignado') AND o.horaInicioOrigen = null ORDER BY o.fechaServicio")
	public List<OrdenServicio> buscarPorEstadoEnProcesoSinHoraInicioOrigen();
	
	@Query("SELECT o FROM OrdenServicio o WHERE o.pasajero.empresa.codEmpresa = :codigoEmpresa AND o.estado = 'Terminado' OR o.estado = 'Cancelado' ORDER BY o.fechaServicio")
    public List<OrdenServicio> buscarPorEstadoTerminadasCanceladas(@Param("codigoEmpresa") Integer codigoEmpresa);
	
	@Query("SELECT o FROM OrdenServicio o WHERE o.estado = 'Terminado' OR o.estado = 'Cancelado' ORDER BY o.fechaServicio")
    public List<OrdenServicio> buscarPorEstadoTerminadasCanceladas();	
	
	@Query("SELECT o FROM OrdenServicio o WHERE o.pasajero.codigo = :codigoPasajero ORDER BY o.fechaServicio ASC")
    public List<OrdenServicio> buscarPorPasajero(@Param("codigoPasajero") Integer codigoPasajero, Pageable pageable);
	
	@Query("SELECT o FROM OrdenServicio o WHERE "
			+ "o.pasajero.empresa.codEmpresa = :codigoEmpresa AND (o.estado = 'Terminado' OR o.estado = 'Cancelado') "
			+ "AND o.fechaServicio BETWEEN (case when (:isFiltroFecha = true) then :fechaDesde else o.fechaServicio end) AND (case when (:isFiltroFecha = true) then :fechaHasta else o.fechaServicio end) "
			+ "AND (hour(o.horaServicio)*60 + minute(o.horaServicio)) BETWEEN (case when (:isFiltroHora = true) then (hour(:horaDesde)*60 + minute(:horaDesde)) else (hour(o.horaServicio)*60 + minute(o.horaServicio)) end) AND (case when (:isFiltroHora = true) then (hour(:horaHasta)*60 + minute(:horaHasta)) else (hour(o.horaServicio)*60 + minute(o.horaServicio)) end) "
			+ "AND (str(day(o.fechaPago)||month(o.fechaPago)||year(o.fechaPago)) like (case when (:isFiltroFechaPago = true) then str(day(:fechaPago)||month(:fechaPago)||year(:fechaPago)) else ('%%') end) OR :isFiltroFechaPago = false) "
			+ "AND (str(day(o.estadoCuentaEmpresa.fechaCierre)||month(o.estadoCuentaEmpresa.fechaCierre)||year(o.estadoCuentaEmpresa.fechaCierre)) like (case when (:isFiltroFechaCierre = true) then str(day(:fechaCierre)||month(:fechaCierre)||year(:fechaCierre)) else ('%%') end) OR :isFiltroFechaCierre = false) "
			+ "AND ((o.pasajero.nombres||' '||o.pasajero.apellidos||' '||o.pasajero.numDocumento) like %:pasajero% OR :isFiltroPasajero = false ) "
			+ "AND ((o.solicitante.login) like %:solicitante% OR :isFiltroSolicitante = false ) "
			+ "AND ((o.centroCosto.nombre) like %:centroCosto% OR :isFiltroCentroCosto = false ) "
			+ "AND ((o.tipoPago = 'Contado') OR :isFiltroContado = false ) "
			+ "AND ((o.tipoPago = 'Credito') OR :isFiltroCredito = false ) "
			+ "ORDER BY o.fechaServicio")
    public List<OrdenServicio> buscarPorEstadoTerminadasCanceladas(
    		@Param("codigoEmpresa") Integer codigoEmpresa,
    		@Param("isFiltroFecha") boolean chkFechas, 
    		@Param("fechaDesde") Date fechaDesde, 
    		@Param("fechaHasta") Date fechaHasta,
    		@Param("isFiltroHora") boolean chkHoras, 
    		@Param("horaDesde") Date HoraDesde, 
    		@Param("horaHasta") Date HoraHasta,
    		@Param("isFiltroFechaCierre") boolean chkFechaCierre, 
    		@Param("fechaCierre") Date fechaCierre,
    		@Param("isFiltroFechaPago") boolean chkFechaPago,
    		@Param("fechaPago") Date fechaPago,
    		@Param("isFiltroPasajero") boolean chkPasajero,
    		@Param("pasajero") String pasajero,
    		@Param("isFiltroSolicitante") boolean chkSolicitante,
    		@Param("solicitante") String solicitante,
    		@Param("isFiltroContado") boolean chkContado,
    		@Param("isFiltroCredito") boolean chkCredito,
    		@Param("isFiltroCentroCosto") boolean chkCentroCosto,
    		@Param("centroCosto") String centroCosto
    		);
	
	@Query("SELECT o FROM OrdenServicio o WHERE "
			+ "(o.estado = 'Terminado' OR o.estado = 'Cancelado') "
			+ "AND o.fechaServicio BETWEEN (case when (:isFiltroFecha = true) then :fechaDesde else o.fechaServicio end) AND (case when (:isFiltroFecha = true) then :fechaHasta else o.fechaServicio end) "
			+ "AND (hour(o.horaServicio)*60 + minute(o.horaServicio)) BETWEEN (case when (:isFiltroHora = true) then (hour(:horaDesde)*60 + minute(:horaDesde)) else (hour(o.horaServicio)*60 + minute(o.horaServicio)) end) AND (case when (:isFiltroHora = true) then (hour(:horaHasta)*60 + minute(:horaHasta)) else (hour(o.horaServicio)*60 + minute(o.horaServicio)) end) "
			+ "AND (str(day(o.fechaPago)||month(o.fechaPago)||year(o.fechaPago)) like (case when (:isFiltroFechaPago = true) then str(day(:fechaPago)||month(:fechaPago)||year(:fechaPago)) else ('%%') end) OR :isFiltroFechaPago = false) "
			+ "AND (str(day(o.estadoCuentaEmpresa.fechaCierre)||month(o.estadoCuentaEmpresa.fechaCierre)||year(o.estadoCuentaEmpresa.fechaCierre)) like (case when (:isFiltroFechaCierre = true) then str(day(:fechaCierre)||month(:fechaCierre)||year(:fechaCierre)) else ('%%') end) OR :isFiltroFechaCierre = false) "
			+ "AND ((o.pasajero.nombres||' '||o.pasajero.apellidos||' '||o.pasajero.numDocumento) like %:pasajero% OR :isFiltroPasajero = false ) "
			+ "AND ((o.solicitante.login) like %:solicitante% OR :isFiltroSolicitante = false ) "
			+ "AND ((o.centroCosto.nombre) like %:centroCosto% OR :isFiltroCentroCosto = false ) "
			+ "AND ((o.tipoPago = 'Contado') OR :isFiltroContado = false ) "
			+ "AND ((o.tipoPago = 'Credito') OR :isFiltroCredito = false ) "
			+ "ORDER BY o.fechaServicio")
    public List<OrdenServicio> buscarPorEstadoTerminadasCanceladas(
    		@Param("isFiltroFecha") boolean chkFechas, 
    		@Param("fechaDesde") Date fechaDesde, 
    		@Param("fechaHasta") Date fechaHasta,
    		@Param("isFiltroHora") boolean chkHoras, 
    		@Param("horaDesde") Date HoraDesde, 
    		@Param("horaHasta") Date HoraHasta,
    		@Param("isFiltroFechaCierre") boolean chkFechaCierre, 
    		@Param("fechaCierre") Date fechaCierre,
    		@Param("isFiltroFechaPago") boolean chkFechaPago,
    		@Param("fechaPago") Date fechaPago,
    		@Param("isFiltroPasajero") boolean chkPasajero,
    		@Param("pasajero") String pasajero,
    		@Param("isFiltroSolicitante") boolean chkSolicitante,
    		@Param("solicitante") String solicitante,
    		@Param("isFiltroContado") boolean chkContado,
    		@Param("isFiltroCredito") boolean chkCredito,
    		@Param("isFiltroCentroCosto") boolean chkCentroCosto,
    		@Param("centroCosto") String centroCosto
    		);
}
